1use crate::ext::io::*;
3use crate::scripts::base::*;
4use crate::types::*;
5use crate::utils::lossless_audio::*;
6use crate::utils::pcm::*;
7use crate::utils::struct_pack::*;
8use anyhow::Result;
9use int_enum::IntEnum;
10use msg_tool_macro::*;
11use overf::wrapping;
12use std::io::{Read, Seek, Write};
13
14#[derive(Debug)]
15pub struct PcmBuilder {}
17
18impl PcmBuilder {
19 pub fn new() -> Self {
21 Self {}
22 }
23}
24
25impl ScriptBuilder for PcmBuilder {
26 fn default_encoding(&self) -> Encoding {
27 Encoding::Utf8
28 }
29
30 fn build_script(
31 &self,
32 buf: Vec<u8>,
33 _filename: &str,
34 _encoding: Encoding,
35 _archive_encoding: Encoding,
36 config: &ExtraConfig,
37 _archive: Option<&Box<dyn Script>>,
38 ) -> Result<Box<dyn Script + Send + Sync>> {
39 Ok(Box::new(Pcm::new(MemReader::new(buf), config)?))
40 }
41
42 fn build_script_from_file(
43 &self,
44 filename: &str,
45 _encoding: Encoding,
46 _archive_encoding: Encoding,
47 config: &ExtraConfig,
48 _archive: Option<&Box<dyn Script>>,
49 ) -> Result<Box<dyn Script + Send + Sync>> {
50 let file = std::fs::File::open(filename)?;
51 let f = std::io::BufReader::new(file);
52 Ok(Box::new(Pcm::new(f, config)?))
53 }
54
55 fn build_script_from_reader<'a>(
56 &self,
57 reader: Box<dyn ReadSeek + Send + Sync + 'a>,
58 _filename: &str,
59 _encoding: Encoding,
60 _archive_encoding: Encoding,
61 config: &ExtraConfig,
62 _archive: Option<&Box<dyn Script>>,
63 ) -> Result<Box<dyn Script + Send + Sync + 'a>> {
64 Ok(Box::new(Pcm::new(reader, config)?))
65 }
66
67 fn extensions(&self) -> &'static [&'static str] {
68 &["pcm"]
69 }
70
71 fn script_type(&self) -> &'static ScriptType {
72 &ScriptType::CircusPcm
73 }
74
75 fn is_this_format(&self, _filename: &str, buf: &[u8], buf_len: usize) -> Option<u8> {
76 if buf_len >= 4 && buf.starts_with(b"XPCM") {
77 Some(10)
78 } else {
79 None
80 }
81 }
82
83 fn is_audio(&self) -> bool {
84 true
85 }
86}
87
88#[derive(Debug, IntEnum)]
89#[repr(u32)]
90enum Mode {
91 Raw = 0,
92 Lzss = 1,
93 Adpcm = 2,
94 Zlib = 3,
95 Ogg = 5,
96}
97
98#[derive(Debug, StructPack, StructUnpack)]
99struct Header {
100 src_size: u32,
101 _mode: u32,
102 #[skip_pack_if(self.mode() != 5)]
103 #[skip_unpack_if((_mode & 0xFF) != 5)]
104 ogg_size: u32,
105 #[skip_pack_if(self.mode() == 5)]
106 #[skip_unpack_if((_mode & 0xFF) == 5)]
107 pcm: Option<PcmFormat>,
108}
109
110impl Header {
111 pub fn mode(&self) -> u32 {
112 self._mode & 0xFF
113 }
114
115 pub fn extra(&self) -> u32 {
116 (self._mode >> 8) & 0xFF
117 }
118}
119
120#[derive(Debug)]
121pub struct Pcm {
123 header: Header,
124 data: MemReader,
125 config: ExtraConfig,
126}
127
128impl Pcm {
129 pub fn new<R: Read + Seek>(mut reader: R, config: &ExtraConfig) -> Result<Self> {
134 let mut magic = [0u8; 4];
135 reader.read_exact(&mut magic)?;
136 if &magic != b"XPCM" {
137 return Err(anyhow::anyhow!("Invalid PCM header magic: {:?}", magic));
138 }
139 let header = Header::unpack(&mut reader, false, Encoding::Utf8, &None)?;
140 let mode = Mode::try_from(header.mode())
141 .map_err(|_| anyhow::anyhow!("Unsupported PCM mode: {}", header.mode()))?;
142 let data = match mode {
143 Mode::Ogg => {
144 if header.ogg_size == 0 {
145 return Err(anyhow::anyhow!("Invalid OGG size in PCM header"));
146 }
147 let mut data = vec![0u8; header.ogg_size as usize];
148 reader.read_exact(&mut data)?;
149 data
150 }
151 Mode::Raw => {
152 let mut data = vec![0u8; header.src_size as usize];
153 reader.read_exact(&mut data)?;
154 data
155 }
156 Mode::Adpcm => Self::decode_adpcm(&mut reader, header.src_size as usize)?,
157 _ => {
158 PcmDecoder::new(reader, header.src_size as usize, header.extra(), mode)?.unpack()?
159 }
160 };
161 Ok(Self {
162 header,
163 data: MemReader::new(data),
164 config: config.clone(),
165 })
166 }
167
168 fn decode_adpcm<R: Read + Seek>(mut input: R, pcm_size: usize) -> Result<Vec<u8>> {
169 let input_len = input.stream_length()? - input.stream_position()?;
170 let mut output = Vec::with_capacity(pcm_size);
171 let mut table = [0u32; 6];
172 let mut channel = 0;
173 let mut src = 0;
174 let mut dst = 0;
175 while src < input_len && dst < pcm_size as u32 {
176 let data = input.read_i8()?;
177 src += 1;
178 table[channel * 3] =
179 table[channel * 3].wrapping_add((data as u32) << (table[channel * 3 + 1] & 0xFF));
180 if data == 0 {
181 if table[channel * 3 + 1] != 0 {
182 table[channel * 3 + 1] = table[channel * 3 + 1].wrapping_sub(1);
183 }
184 } else if data == 0x7F || data == -0x80 {
185 if table[channel * 3 + 1] != 8 {
186 table[channel * 3 + 1] = table[channel * 3 + 1].wrapping_add(1);
187 }
188 }
189 output.push(table[channel * 3] as u8);
190 output.push((table[channel * 3] >> 8) as u8);
191 channel = 1 - channel;
192 dst += 2;
193 }
194 Ok(output)
195 }
196}
197
198impl Script for Pcm {
199 fn default_output_script_type(&self) -> OutputScriptType {
200 OutputScriptType::Custom
201 }
202
203 fn default_format_type(&self) -> FormatOptions {
204 FormatOptions::None
205 }
206
207 fn is_output_supported(&self, output: OutputScriptType) -> bool {
208 matches!(output, OutputScriptType::Custom)
209 }
210
211 fn custom_output_extension<'a>(&'a self) -> &'a str {
212 if self.header.mode() == 5 {
213 "ogg"
214 } else {
215 self.config.lossless_audio_fmt.as_ref()
216 }
217 }
218
219 fn custom_export(&self, filename: &std::path::Path, _encoding: Encoding) -> Result<()> {
220 let mut writer = std::fs::File::create(filename)?;
221 if self.header.mode() == 5 {
222 writer.write_all(&self.data.data)?;
223 } else {
224 let fmt = self
225 .header
226 .pcm
227 .as_ref()
228 .ok_or_else(|| anyhow::anyhow!("PCM format not found in header"))?;
229 write_audio(fmt, self.data.to_ref(), writer, &self.config)?;
230 }
231 Ok(())
232 }
233}
234
235const UNK_43A254: [u8; 320] = [
236 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
237 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
238 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
239 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
240 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
241 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
242 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
243 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
244 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
245 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
246 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
247 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
248 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
249 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
250 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
251 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
252 0x55, 0x05, 0x00, 0x00, 0x55, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xAA, 0x0A, 0x00, 0x00,
253 0xAA, 0x0A, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
254 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
255 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
256];
257const DWORD_43A358: [i32; 2048] = [
258 0x1000, 0x0000, 0x0FFF, 0x0006, 0x0FFF, 0x000C, 0x0FFF, 0x0012, 0x0FFF, 0x0019, 0x0FFF, 0x001F,
259 0x0FFF, 0x0025, 0x0FFF, 0x002B, 0x0FFF, 0x0032, 0x0FFF, 0x0038, 0x0FFF, 0x003E, 0x0FFF, 0x0045,
260 0x0FFF, 0x004B, 0x0FFF, 0x0051, 0x0FFF, 0x0057, 0x0FFE, 0x005E, 0x0FFE, 0x0064, 0x0FFE, 0x006A,
261 0x0FFE, 0x0071, 0x0FFE, 0x0077, 0x0FFE, 0x007D, 0x0FFD, 0x0083, 0x0FFD, 0x008A, 0x0FFD, 0x0090,
262 0x0FFD, 0x0096, 0x0FFC, 0x009D, 0x0FFC, 0x00A3, 0x0FFC, 0x00A9, 0x0FFC, 0x00AF, 0x0FFB, 0x00B6,
263 0x0FFB, 0x00BC, 0x0FFB, 0x00C2, 0x0FFB, 0x00C8, 0x0FFA, 0x00CF, 0x0FFA, 0x00D5, 0x0FFA, 0x00DB,
264 0x0FF9, 0x00E2, 0x0FF9, 0x00E8, 0x0FF9, 0x00EE, 0x0FF8, 0x00F4, 0x0FF8, 0x00FB, 0x0FF7, 0x0101,
265 0x0FF7, 0x0107, 0x0FF7, 0x010D, 0x0FF6, 0x0114, 0x0FF6, 0x011A, 0x0FF5, 0x0120, 0x0FF5, 0x0127,
266 0x0FF4, 0x012D, 0x0FF4, 0x0133, 0x0FF3, 0x0139, 0x0FF3, 0x0140, 0x0FF2, 0x0146, 0x0FF2, 0x014C,
267 0x0FF1, 0x0152, 0x0FF1, 0x0159, 0x0FF0, 0x015F, 0x0FF0, 0x0165, 0x0FEF, 0x016B, 0x0FEF, 0x0172,
268 0x0FEE, 0x0178, 0x0FEE, 0x017E, 0x0FED, 0x0184, 0x0FEC, 0x018B, 0x0FEC, 0x0191, 0x0FEB, 0x0197,
269 0x0FEB, 0x019D, 0x0FEA, 0x01A4, 0x0FE9, 0x01AA, 0x0FE9, 0x01B0, 0x0FE8, 0x01B6, 0x0FE7, 0x01BD,
270 0x0FE7, 0x01C3, 0x0FE6, 0x01C9, 0x0FE5, 0x01CF, 0x0FE4, 0x01D6, 0x0FE4, 0x01DC, 0x0FE3, 0x01E2,
271 0x0FE2, 0x01E8, 0x0FE1, 0x01EF, 0x0FE1, 0x01F5, 0x0FE0, 0x01FB, 0x0FDF, 0x0201, 0x0FDE, 0x0208,
272 0x0FDE, 0x020E, 0x0FDD, 0x0214, 0x0FDC, 0x021A, 0x0FDB, 0x0221, 0x0FDA, 0x0227, 0x0FD9, 0x022D,
273 0x0FD9, 0x0233, 0x0FD8, 0x0239, 0x0FD7, 0x0240, 0x0FD6, 0x0246, 0x0FD5, 0x024C, 0x0FD4, 0x0252,
274 0x0FD3, 0x0259, 0x0FD2, 0x025F, 0x0FD1, 0x0265, 0x0FD0, 0x026B, 0x0FCF, 0x0271, 0x0FCE, 0x0278,
275 0x0FCD, 0x027E, 0x0FCC, 0x0284, 0x0FCB, 0x028A, 0x0FCA, 0x0290, 0x0FC9, 0x0297, 0x0FC8, 0x029D,
276 0x0FC7, 0x02A3, 0x0FC6, 0x02A9, 0x0FC5, 0x02AF, 0x0FC4, 0x02B6, 0x0FC3, 0x02BC, 0x0FC2, 0x02C2,
277 0x0FC1, 0x02C8, 0x0FC0, 0x02CE, 0x0FBF, 0x02D5, 0x0FBE, 0x02DB, 0x0FBD, 0x02E1, 0x0FBB, 0x02E7,
278 0x0FBA, 0x02ED, 0x0FB9, 0x02F3, 0x0FB8, 0x02FA, 0x0FB7, 0x0300, 0x0FB6, 0x0306, 0x0FB4, 0x030C,
279 0x0FB3, 0x0312, 0x0FB2, 0x0318, 0x0FB1, 0x031F, 0x0FB0, 0x0325, 0x0FAE, 0x032B, 0x0FAD, 0x0331,
280 0x0FAC, 0x0337, 0x0FAB, 0x033D, 0x0FA9, 0x0344, 0x0FA8, 0x034A, 0x0FA7, 0x0350, 0x0FA5, 0x0356,
281 0x0FA4, 0x035C, 0x0FA3, 0x0362, 0x0FA1, 0x0368, 0x0FA0, 0x036F, 0x0F9F, 0x0375, 0x0F9D, 0x037B,
282 0x0F9C, 0x0381, 0x0F9B, 0x0387, 0x0F99, 0x038D, 0x0F98, 0x0393, 0x0F96, 0x0399, 0x0F95, 0x03A0,
283 0x0F94, 0x03A6, 0x0F92, 0x03AC, 0x0F91, 0x03B2, 0x0F8F, 0x03B8, 0x0F8E, 0x03BE, 0x0F8C, 0x03C4,
284 0x0F8B, 0x03CA, 0x0F89, 0x03D0, 0x0F88, 0x03D7, 0x0F86, 0x03DD, 0x0F85, 0x03E3, 0x0F83, 0x03E9,
285 0x0F82, 0x03EF, 0x0F80, 0x03F5, 0x0F7F, 0x03FB, 0x0F7D, 0x0401, 0x0F7B, 0x0407, 0x0F7A, 0x040D,
286 0x0F78, 0x0413, 0x0F77, 0x041A, 0x0F75, 0x0420, 0x0F73, 0x0426, 0x0F72, 0x042C, 0x0F70, 0x0432,
287 0x0F6E, 0x0438, 0x0F6D, 0x043E, 0x0F6B, 0x0444, 0x0F69, 0x044A, 0x0F68, 0x0450, 0x0F66, 0x0456,
288 0x0F64, 0x045C, 0x0F63, 0x0462, 0x0F61, 0x0468, 0x0F5F, 0x046E, 0x0F5D, 0x0474, 0x0F5C, 0x047A,
289 0x0F5A, 0x0480, 0x0F58, 0x0486, 0x0F56, 0x048C, 0x0F55, 0x0492, 0x0F53, 0x0498, 0x0F51, 0x049E,
290 0x0F4F, 0x04A5, 0x0F4D, 0x04AB, 0x0F4B, 0x04B1, 0x0F4A, 0x04B7, 0x0F48, 0x04BD, 0x0F46, 0x04C3,
291 0x0F44, 0x04C9, 0x0F42, 0x04CF, 0x0F40, 0x04D5, 0x0F3E, 0x04DB, 0x0F3C, 0x04E0, 0x0F3B, 0x04E6,
292 0x0F39, 0x04EC, 0x0F37, 0x04F2, 0x0F35, 0x04F8, 0x0F33, 0x04FE, 0x0F31, 0x0504, 0x0F2F, 0x050A,
293 0x0F2D, 0x0510, 0x0F2B, 0x0516, 0x0F29, 0x051C, 0x0F27, 0x0522, 0x0F25, 0x0528, 0x0F23, 0x052E,
294 0x0F21, 0x0534, 0x0F1F, 0x053A, 0x0F1D, 0x0540, 0x0F1B, 0x0546, 0x0F18, 0x054C, 0x0F16, 0x0552,
295 0x0F14, 0x0558, 0x0F12, 0x055D, 0x0F10, 0x0563, 0x0F0E, 0x0569, 0x0F0C, 0x056F, 0x0F0A, 0x0575,
296 0x0F08, 0x057B, 0x0F05, 0x0581, 0x0F03, 0x0587, 0x0F01, 0x058D, 0x0EFF, 0x0593, 0x0EFD, 0x0599,
297 0x0EFA, 0x059E, 0x0EF8, 0x05A4, 0x0EF6, 0x05AA, 0x0EF4, 0x05B0, 0x0EF2, 0x05B6, 0x0EEF, 0x05BC,
298 0x0EED, 0x05C2, 0x0EEB, 0x05C7, 0x0EE8, 0x05CD, 0x0EE6, 0x05D3, 0x0EE4, 0x05D9, 0x0EE2, 0x05DF,
299 0x0EDF, 0x05E5, 0x0EDD, 0x05EB, 0x0EDB, 0x05F0, 0x0ED8, 0x05F6, 0x0ED6, 0x05FC, 0x0ED4, 0x0602,
300 0x0ED1, 0x0608, 0x0ECF, 0x060E, 0x0ECD, 0x0613, 0x0ECA, 0x0619, 0x0EC8, 0x061F, 0x0EC5, 0x0625,
301 0x0EC3, 0x062B, 0x0EC0, 0x0630, 0x0EBE, 0x0636, 0x0EBC, 0x063C, 0x0EB9, 0x0642, 0x0EB7, 0x0648,
302 0x0EB4, 0x064D, 0x0EB2, 0x0653, 0x0EAF, 0x0659, 0x0EAD, 0x065F, 0x0EAA, 0x0664, 0x0EA8, 0x066A,
303 0x0EA5, 0x0670, 0x0EA3, 0x0676, 0x0EA0, 0x067B, 0x0E9E, 0x0681, 0x0E9B, 0x0687, 0x0E98, 0x068D,
304 0x0E96, 0x0692, 0x0E93, 0x0698, 0x0E91, 0x069E, 0x0E8E, 0x06A3, 0x0E8B, 0x06A9, 0x0E89, 0x06AF,
305 0x0E86, 0x06B5, 0x0E84, 0x06BA, 0x0E81, 0x06C0, 0x0E7E, 0x06C6, 0x0E7C, 0x06CB, 0x0E79, 0x06D1,
306 0x0E76, 0x06D7, 0x0E74, 0x06DC, 0x0E71, 0x06E2, 0x0E6E, 0x06E8, 0x0E6B, 0x06ED, 0x0E69, 0x06F3,
307 0x0E66, 0x06F9, 0x0E63, 0x06FE, 0x0E60, 0x0704, 0x0E5E, 0x070A, 0x0E5B, 0x070F, 0x0E58, 0x0715,
308 0x0E55, 0x071B, 0x0E53, 0x0720, 0x0E50, 0x0726, 0x0E4D, 0x072B, 0x0E4A, 0x0731, 0x0E47, 0x0737,
309 0x0E44, 0x073C, 0x0E42, 0x0742, 0x0E3F, 0x0748, 0x0E3C, 0x074D, 0x0E39, 0x0753, 0x0E36, 0x0758,
310 0x0E33, 0x075E, 0x0E30, 0x0763, 0x0E2D, 0x0769, 0x0E2B, 0x076F, 0x0E28, 0x0774, 0x0E25, 0x077A,
311 0x0E22, 0x077F, 0x0E1F, 0x0785, 0x0E1C, 0x078A, 0x0E19, 0x0790, 0x0E16, 0x0795, 0x0E13, 0x079B,
312 0x0E10, 0x07A0, 0x0E0D, 0x07A6, 0x0E0A, 0x07AC, 0x0E07, 0x07B1, 0x0E04, 0x07B7, 0x0E01, 0x07BC,
313 0x0DFE, 0x07C2, 0x0DFB, 0x07C7, 0x0DF8, 0x07CD, 0x0DF5, 0x07D2, 0x0DF2, 0x07D7, 0x0DEE, 0x07DD,
314 0x0DEB, 0x07E2, 0x0DE8, 0x07E8, 0x0DE5, 0x07ED, 0x0DE2, 0x07F3, 0x0DDF, 0x07F8, 0x0DDC, 0x07FE,
315 0x0DD9, 0x0803, 0x0DD5, 0x0809, 0x0DD2, 0x080E, 0x0DCF, 0x0813, 0x0DCC, 0x0819, 0x0DC9, 0x081E,
316 0x0DC6, 0x0824, 0x0DC2, 0x0829, 0x0DBF, 0x082E, 0x0DBC, 0x0834, 0x0DB9, 0x0839, 0x0DB6, 0x083F,
317 0x0DB2, 0x0844, 0x0DAF, 0x0849, 0x0DAC, 0x084F, 0x0DA9, 0x0854, 0x0DA5, 0x085A, 0x0DA2, 0x085F,
318 0x0D9F, 0x0864, 0x0D9B, 0x086A, 0x0D98, 0x086F, 0x0D95, 0x0874, 0x0D91, 0x087A, 0x0D8E, 0x087F,
319 0x0D8B, 0x0884, 0x0D87, 0x088A, 0x0D84, 0x088F, 0x0D81, 0x0894, 0x0D7D, 0x0899, 0x0D7A, 0x089F,
320 0x0D77, 0x08A4, 0x0D73, 0x08A9, 0x0D70, 0x08AF, 0x0D6C, 0x08B4, 0x0D69, 0x08B9, 0x0D65, 0x08BE,
321 0x0D62, 0x08C4, 0x0D5F, 0x08C9, 0x0D5B, 0x08CE, 0x0D58, 0x08D3, 0x0D54, 0x08D9, 0x0D51, 0x08DE,
322 0x0D4D, 0x08E3, 0x0D4A, 0x08E8, 0x0D46, 0x08EE, 0x0D43, 0x08F3, 0x0D3F, 0x08F8, 0x0D3C, 0x08FD,
323 0x0D38, 0x0902, 0x0D35, 0x0908, 0x0D31, 0x090D, 0x0D2D, 0x0912, 0x0D2A, 0x0917, 0x0D26, 0x091C,
324 0x0D23, 0x0921, 0x0D1F, 0x0927, 0x0D1C, 0x092C, 0x0D18, 0x0931, 0x0D14, 0x0936, 0x0D11, 0x093B,
325 0x0D0D, 0x0940, 0x0D09, 0x0945, 0x0D06, 0x094B, 0x0D02, 0x0950, 0x0CFE, 0x0955, 0x0CFB, 0x095A,
326 0x0CF7, 0x095F, 0x0CF3, 0x0964, 0x0CF0, 0x0969, 0x0CEC, 0x096E, 0x0CE8, 0x0973, 0x0CE5, 0x0978,
327 0x0CE1, 0x097D, 0x0CDD, 0x0982, 0x0CD9, 0x0987, 0x0CD6, 0x098D, 0x0CD2, 0x0992, 0x0CCE, 0x0997,
328 0x0CCA, 0x099C, 0x0CC7, 0x09A1, 0x0CC3, 0x09A6, 0x0CBF, 0x09AB, 0x0CBB, 0x09B0, 0x0CB7, 0x09B5,
329 0x0CB4, 0x09BA, 0x0CB0, 0x09BF, 0x0CAC, 0x09C4, 0x0CA8, 0x09C9, 0x0CA4, 0x09CE, 0x0CA0, 0x09D3,
330 0x0C9D, 0x09D7, 0x0C99, 0x09DC, 0x0C95, 0x09E1, 0x0C91, 0x09E6, 0x0C8D, 0x09EB, 0x0C89, 0x09F0,
331 0x0C85, 0x09F5, 0x0C81, 0x09FA, 0x0C7D, 0x09FF, 0x0C79, 0x0A04, 0x0C76, 0x0A09, 0x0C72, 0x0A0E,
332 0x0C6E, 0x0A12, 0x0C6A, 0x0A17, 0x0C66, 0x0A1C, 0x0C62, 0x0A21, 0x0C5E, 0x0A26, 0x0C5A, 0x0A2B,
333 0x0C56, 0x0A30, 0x0C52, 0x0A35, 0x0C4E, 0x0A39, 0x0C4A, 0x0A3E, 0x0C46, 0x0A43, 0x0C42, 0x0A48,
334 0x0C3E, 0x0A4D, 0x0C3A, 0x0A51, 0x0C36, 0x0A56, 0x0C31, 0x0A5B, 0x0C2D, 0x0A60, 0x0C29, 0x0A65,
335 0x0C25, 0x0A69, 0x0C21, 0x0A6E, 0x0C1D, 0x0A73, 0x0C19, 0x0A78, 0x0C15, 0x0A7C, 0x0C11, 0x0A81,
336 0x0C0D, 0x0A86, 0x0C08, 0x0A8B, 0x0C04, 0x0A8F, 0x0C00, 0x0A94, 0x0BFC, 0x0A99, 0x0BF8, 0x0A9D,
337 0x0BF4, 0x0AA2, 0x0BEF, 0x0AA7, 0x0BEB, 0x0AAC, 0x0BE7, 0x0AB0, 0x0BE3, 0x0AB5, 0x0BDF, 0x0ABA,
338 0x0BDA, 0x0ABE, 0x0BD6, 0x0AC3, 0x0BD2, 0x0AC8, 0x0BCE, 0x0ACC, 0x0BCA, 0x0AD1, 0x0BC5, 0x0AD5,
339 0x0BC1, 0x0ADA, 0x0BBD, 0x0ADF, 0x0BB8, 0x0AE3, 0x0BB4, 0x0AE8, 0x0BB0, 0x0AEC, 0x0BAC, 0x0AF1,
340 0x0BA7, 0x0AF6, 0x0BA3, 0x0AFA, 0x0B9F, 0x0AFF, 0x0B9A, 0x0B03, 0x0B96, 0x0B08, 0x0B92, 0x0B0C,
341 0x0B8D, 0x0B11, 0x0B89, 0x0B15, 0x0B85, 0x0B1A, 0x0B80, 0x0B1F, 0x0B7C, 0x0B23, 0x0B78, 0x0B28,
342 0x0B73, 0x0B2C, 0x0B6F, 0x0B31, 0x0B6A, 0x0B35, 0x0B66, 0x0B3A, 0x0B62, 0x0B3E, 0x0B5D, 0x0B42,
343 0x0B59, 0x0B47, 0x0B54, 0x0B4B, 0x0B50, 0x0B50, 0x0B4B, 0x0B54, 0x0B47, 0x0B59, 0x0B42, 0x0B5D,
344 0x0B3E, 0x0B62, 0x0B3A, 0x0B66, 0x0B35, 0x0B6A, 0x0B31, 0x0B6F, 0x0B2C, 0x0B73, 0x0B28, 0x0B78,
345 0x0B23, 0x0B7C, 0x0B1F, 0x0B80, 0x0B1A, 0x0B85, 0x0B15, 0x0B89, 0x0B11, 0x0B8D, 0x0B0C, 0x0B92,
346 0x0B08, 0x0B96, 0x0B03, 0x0B9A, 0x0AFF, 0x0B9F, 0x0AFA, 0x0BA3, 0x0AF6, 0x0BA7, 0x0AF1, 0x0BAC,
347 0x0AEC, 0x0BB0, 0x0AE8, 0x0BB4, 0x0AE3, 0x0BB8, 0x0ADF, 0x0BBD, 0x0ADA, 0x0BC1, 0x0AD5, 0x0BC5,
348 0x0AD1, 0x0BCA, 0x0ACC, 0x0BCE, 0x0AC8, 0x0BD2, 0x0AC3, 0x0BD6, 0x0ABE, 0x0BDA, 0x0ABA, 0x0BDF,
349 0x0AB5, 0x0BE3, 0x0AB0, 0x0BE7, 0x0AAC, 0x0BEB, 0x0AA7, 0x0BEF, 0x0AA2, 0x0BF4, 0x0A9D, 0x0BF8,
350 0x0A99, 0x0BFC, 0x0A94, 0x0C00, 0x0A8F, 0x0C04, 0x0A8B, 0x0C08, 0x0A86, 0x0C0D, 0x0A81, 0x0C11,
351 0x0A7C, 0x0C15, 0x0A78, 0x0C19, 0x0A73, 0x0C1D, 0x0A6E, 0x0C21, 0x0A69, 0x0C25, 0x0A65, 0x0C29,
352 0x0A60, 0x0C2D, 0x0A5B, 0x0C31, 0x0A56, 0x0C36, 0x0A51, 0x0C3A, 0x0A4D, 0x0C3E, 0x0A48, 0x0C42,
353 0x0A43, 0x0C46, 0x0A3E, 0x0C4A, 0x0A39, 0x0C4E, 0x0A35, 0x0C52, 0x0A30, 0x0C56, 0x0A2B, 0x0C5A,
354 0x0A26, 0x0C5E, 0x0A21, 0x0C62, 0x0A1C, 0x0C66, 0x0A17, 0x0C6A, 0x0A12, 0x0C6E, 0x0A0E, 0x0C72,
355 0x0A09, 0x0C76, 0x0A04, 0x0C79, 0x09FF, 0x0C7D, 0x09FA, 0x0C81, 0x09F5, 0x0C85, 0x09F0, 0x0C89,
356 0x09EB, 0x0C8D, 0x09E6, 0x0C91, 0x09E1, 0x0C95, 0x09DC, 0x0C99, 0x09D7, 0x0C9D, 0x09D3, 0x0CA0,
357 0x09CE, 0x0CA4, 0x09C9, 0x0CA8, 0x09C4, 0x0CAC, 0x09BF, 0x0CB0, 0x09BA, 0x0CB4, 0x09B5, 0x0CB7,
358 0x09B0, 0x0CBB, 0x09AB, 0x0CBF, 0x09A6, 0x0CC3, 0x09A1, 0x0CC7, 0x099C, 0x0CCA, 0x0997, 0x0CCE,
359 0x0992, 0x0CD2, 0x098D, 0x0CD6, 0x0987, 0x0CD9, 0x0982, 0x0CDD, 0x097D, 0x0CE1, 0x0978, 0x0CE5,
360 0x0973, 0x0CE8, 0x096E, 0x0CEC, 0x0969, 0x0CF0, 0x0964, 0x0CF3, 0x095F, 0x0CF7, 0x095A, 0x0CFB,
361 0x0955, 0x0CFE, 0x0950, 0x0D02, 0x094B, 0x0D06, 0x0945, 0x0D09, 0x0940, 0x0D0D, 0x093B, 0x0D11,
362 0x0936, 0x0D14, 0x0931, 0x0D18, 0x092C, 0x0D1C, 0x0927, 0x0D1F, 0x0921, 0x0D23, 0x091C, 0x0D26,
363 0x0917, 0x0D2A, 0x0912, 0x0D2D, 0x090D, 0x0D31, 0x0908, 0x0D35, 0x0902, 0x0D38, 0x08FD, 0x0D3C,
364 0x08F8, 0x0D3F, 0x08F3, 0x0D43, 0x08EE, 0x0D46, 0x08E8, 0x0D4A, 0x08E3, 0x0D4D, 0x08DE, 0x0D51,
365 0x08D9, 0x0D54, 0x08D3, 0x0D58, 0x08CE, 0x0D5B, 0x08C9, 0x0D5F, 0x08C4, 0x0D62, 0x08BE, 0x0D65,
366 0x08B9, 0x0D69, 0x08B4, 0x0D6C, 0x08AF, 0x0D70, 0x08A9, 0x0D73, 0x08A4, 0x0D77, 0x089F, 0x0D7A,
367 0x0899, 0x0D7D, 0x0894, 0x0D81, 0x088F, 0x0D84, 0x088A, 0x0D87, 0x0884, 0x0D8B, 0x087F, 0x0D8E,
368 0x087A, 0x0D91, 0x0874, 0x0D95, 0x086F, 0x0D98, 0x086A, 0x0D9B, 0x0864, 0x0D9F, 0x085F, 0x0DA2,
369 0x085A, 0x0DA5, 0x0854, 0x0DA9, 0x084F, 0x0DAC, 0x0849, 0x0DAF, 0x0844, 0x0DB2, 0x083F, 0x0DB6,
370 0x0839, 0x0DB9, 0x0834, 0x0DBC, 0x082E, 0x0DBF, 0x0829, 0x0DC2, 0x0824, 0x0DC6, 0x081E, 0x0DC9,
371 0x0819, 0x0DCC, 0x0813, 0x0DCF, 0x080E, 0x0DD2, 0x0809, 0x0DD5, 0x0803, 0x0DD9, 0x07FE, 0x0DDC,
372 0x07F8, 0x0DDF, 0x07F3, 0x0DE2, 0x07ED, 0x0DE5, 0x07E8, 0x0DE8, 0x07E2, 0x0DEB, 0x07DD, 0x0DEE,
373 0x07D7, 0x0DF2, 0x07D2, 0x0DF5, 0x07CD, 0x0DF8, 0x07C7, 0x0DFB, 0x07C2, 0x0DFE, 0x07BC, 0x0E01,
374 0x07B7, 0x0E04, 0x07B1, 0x0E07, 0x07AC, 0x0E0A, 0x07A6, 0x0E0D, 0x07A0, 0x0E10, 0x079B, 0x0E13,
375 0x0795, 0x0E16, 0x0790, 0x0E19, 0x078A, 0x0E1C, 0x0785, 0x0E1F, 0x077F, 0x0E22, 0x077A, 0x0E25,
376 0x0774, 0x0E28, 0x076F, 0x0E2B, 0x0769, 0x0E2D, 0x0763, 0x0E30, 0x075E, 0x0E33, 0x0758, 0x0E36,
377 0x0753, 0x0E39, 0x074D, 0x0E3C, 0x0748, 0x0E3F, 0x0742, 0x0E42, 0x073C, 0x0E44, 0x0737, 0x0E47,
378 0x0731, 0x0E4A, 0x072B, 0x0E4D, 0x0726, 0x0E50, 0x0720, 0x0E53, 0x071B, 0x0E55, 0x0715, 0x0E58,
379 0x070F, 0x0E5B, 0x070A, 0x0E5E, 0x0704, 0x0E60, 0x06FE, 0x0E63, 0x06F9, 0x0E66, 0x06F3, 0x0E69,
380 0x06ED, 0x0E6B, 0x06E8, 0x0E6E, 0x06E2, 0x0E71, 0x06DC, 0x0E74, 0x06D7, 0x0E76, 0x06D1, 0x0E79,
381 0x06CB, 0x0E7C, 0x06C6, 0x0E7E, 0x06C0, 0x0E81, 0x06BA, 0x0E84, 0x06B5, 0x0E86, 0x06AF, 0x0E89,
382 0x06A9, 0x0E8B, 0x06A3, 0x0E8E, 0x069E, 0x0E91, 0x0698, 0x0E93, 0x0692, 0x0E96, 0x068D, 0x0E98,
383 0x0687, 0x0E9B, 0x0681, 0x0E9E, 0x067B, 0x0EA0, 0x0676, 0x0EA3, 0x0670, 0x0EA5, 0x066A, 0x0EA8,
384 0x0664, 0x0EAA, 0x065F, 0x0EAD, 0x0659, 0x0EAF, 0x0653, 0x0EB2, 0x064D, 0x0EB4, 0x0648, 0x0EB7,
385 0x0642, 0x0EB9, 0x063C, 0x0EBC, 0x0636, 0x0EBE, 0x0630, 0x0EC0, 0x062B, 0x0EC3, 0x0625, 0x0EC5,
386 0x061F, 0x0EC8, 0x0619, 0x0ECA, 0x0613, 0x0ECD, 0x060E, 0x0ECF, 0x0608, 0x0ED1, 0x0602, 0x0ED4,
387 0x05FC, 0x0ED6, 0x05F6, 0x0ED8, 0x05F0, 0x0EDB, 0x05EB, 0x0EDD, 0x05E5, 0x0EDF, 0x05DF, 0x0EE2,
388 0x05D9, 0x0EE4, 0x05D3, 0x0EE6, 0x05CD, 0x0EE8, 0x05C7, 0x0EEB, 0x05C2, 0x0EED, 0x05BC, 0x0EEF,
389 0x05B6, 0x0EF2, 0x05B0, 0x0EF4, 0x05AA, 0x0EF6, 0x05A4, 0x0EF8, 0x059E, 0x0EFA, 0x0599, 0x0EFD,
390 0x0593, 0x0EFF, 0x058D, 0x0F01, 0x0587, 0x0F03, 0x0581, 0x0F05, 0x057B, 0x0F08, 0x0575, 0x0F0A,
391 0x056F, 0x0F0C, 0x0569, 0x0F0E, 0x0563, 0x0F10, 0x055D, 0x0F12, 0x0558, 0x0F14, 0x0552, 0x0F16,
392 0x054C, 0x0F18, 0x0546, 0x0F1B, 0x0540, 0x0F1D, 0x053A, 0x0F1F, 0x0534, 0x0F21, 0x052E, 0x0F23,
393 0x0528, 0x0F25, 0x0522, 0x0F27, 0x051C, 0x0F29, 0x0516, 0x0F2B, 0x0510, 0x0F2D, 0x050A, 0x0F2F,
394 0x0504, 0x0F31, 0x04FE, 0x0F33, 0x04F8, 0x0F35, 0x04F2, 0x0F37, 0x04EC, 0x0F39, 0x04E6, 0x0F3B,
395 0x04E0, 0x0F3C, 0x04DB, 0x0F3E, 0x04D5, 0x0F40, 0x04CF, 0x0F42, 0x04C9, 0x0F44, 0x04C3, 0x0F46,
396 0x04BD, 0x0F48, 0x04B7, 0x0F4A, 0x04B1, 0x0F4B, 0x04AB, 0x0F4D, 0x04A5, 0x0F4F, 0x049E, 0x0F51,
397 0x0498, 0x0F53, 0x0492, 0x0F55, 0x048C, 0x0F56, 0x0486, 0x0F58, 0x0480, 0x0F5A, 0x047A, 0x0F5C,
398 0x0474, 0x0F5D, 0x046E, 0x0F5F, 0x0468, 0x0F61, 0x0462, 0x0F63, 0x045C, 0x0F64, 0x0456, 0x0F66,
399 0x0450, 0x0F68, 0x044A, 0x0F69, 0x0444, 0x0F6B, 0x043E, 0x0F6D, 0x0438, 0x0F6E, 0x0432, 0x0F70,
400 0x042C, 0x0F72, 0x0426, 0x0F73, 0x0420, 0x0F75, 0x041A, 0x0F77, 0x0413, 0x0F78, 0x040D, 0x0F7A,
401 0x0407, 0x0F7B, 0x0401, 0x0F7D, 0x03FB, 0x0F7F, 0x03F5, 0x0F80, 0x03EF, 0x0F82, 0x03E9, 0x0F83,
402 0x03E3, 0x0F85, 0x03DD, 0x0F86, 0x03D7, 0x0F88, 0x03D0, 0x0F89, 0x03CA, 0x0F8B, 0x03C4, 0x0F8C,
403 0x03BE, 0x0F8E, 0x03B8, 0x0F8F, 0x03B2, 0x0F91, 0x03AC, 0x0F92, 0x03A6, 0x0F94, 0x03A0, 0x0F95,
404 0x0399, 0x0F96, 0x0393, 0x0F98, 0x038D, 0x0F99, 0x0387, 0x0F9B, 0x0381, 0x0F9C, 0x037B, 0x0F9D,
405 0x0375, 0x0F9F, 0x036F, 0x0FA0, 0x0368, 0x0FA1, 0x0362, 0x0FA3, 0x035C, 0x0FA4, 0x0356, 0x0FA5,
406 0x0350, 0x0FA7, 0x034A, 0x0FA8, 0x0344, 0x0FA9, 0x033D, 0x0FAB, 0x0337, 0x0FAC, 0x0331, 0x0FAD,
407 0x032B, 0x0FAE, 0x0325, 0x0FB0, 0x031F, 0x0FB1, 0x0318, 0x0FB2, 0x0312, 0x0FB3, 0x030C, 0x0FB4,
408 0x0306, 0x0FB6, 0x0300, 0x0FB7, 0x02FA, 0x0FB8, 0x02F3, 0x0FB9, 0x02ED, 0x0FBA, 0x02E7, 0x0FBB,
409 0x02E1, 0x0FBD, 0x02DB, 0x0FBE, 0x02D5, 0x0FBF, 0x02CE, 0x0FC0, 0x02C8, 0x0FC1, 0x02C2, 0x0FC2,
410 0x02BC, 0x0FC3, 0x02B6, 0x0FC4, 0x02AF, 0x0FC5, 0x02A9, 0x0FC6, 0x02A3, 0x0FC7, 0x029D, 0x0FC8,
411 0x0297, 0x0FC9, 0x0290, 0x0FCA, 0x028A, 0x0FCB, 0x0284, 0x0FCC, 0x027E, 0x0FCD, 0x0278, 0x0FCE,
412 0x0271, 0x0FCF, 0x026B, 0x0FD0, 0x0265, 0x0FD1, 0x025F, 0x0FD2, 0x0259, 0x0FD3, 0x0252, 0x0FD4,
413 0x024C, 0x0FD5, 0x0246, 0x0FD6, 0x0240, 0x0FD7, 0x0239, 0x0FD8, 0x0233, 0x0FD9, 0x022D, 0x0FD9,
414 0x0227, 0x0FDA, 0x0221, 0x0FDB, 0x021A, 0x0FDC, 0x0214, 0x0FDD, 0x020E, 0x0FDE, 0x0208, 0x0FDE,
415 0x0201, 0x0FDF, 0x01FB, 0x0FE0, 0x01F5, 0x0FE1, 0x01EF, 0x0FE1, 0x01E8, 0x0FE2, 0x01E2, 0x0FE3,
416 0x01DC, 0x0FE4, 0x01D6, 0x0FE4, 0x01CF, 0x0FE5, 0x01C9, 0x0FE6, 0x01C3, 0x0FE7, 0x01BD, 0x0FE7,
417 0x01B6, 0x0FE8, 0x01B0, 0x0FE9, 0x01AA, 0x0FE9, 0x01A4, 0x0FEA, 0x019D, 0x0FEB, 0x0197, 0x0FEB,
418 0x0191, 0x0FEC, 0x018B, 0x0FEC, 0x0184, 0x0FED, 0x017E, 0x0FEE, 0x0178, 0x0FEE, 0x0172, 0x0FEF,
419 0x016B, 0x0FEF, 0x0165, 0x0FF0, 0x015F, 0x0FF0, 0x0159, 0x0FF1, 0x0152, 0x0FF1, 0x014C, 0x0FF2,
420 0x0146, 0x0FF2, 0x0140, 0x0FF3, 0x0139, 0x0FF3, 0x0133, 0x0FF4, 0x012D, 0x0FF4, 0x0127, 0x0FF5,
421 0x0120, 0x0FF5, 0x011A, 0x0FF6, 0x0114, 0x0FF6, 0x010D, 0x0FF7, 0x0107, 0x0FF7, 0x0101, 0x0FF7,
422 0x00FB, 0x0FF8, 0x00F4, 0x0FF8, 0x00EE, 0x0FF9, 0x00E8, 0x0FF9, 0x00E2, 0x0FF9, 0x00DB, 0x0FFA,
423 0x00D5, 0x0FFA, 0x00CF, 0x0FFA, 0x00C8, 0x0FFB, 0x00C2, 0x0FFB, 0x00BC, 0x0FFB, 0x00B6, 0x0FFB,
424 0x00AF, 0x0FFC, 0x00A9, 0x0FFC, 0x00A3, 0x0FFC, 0x009D, 0x0FFC, 0x0096, 0x0FFD, 0x0090, 0x0FFD,
425 0x008A, 0x0FFD, 0x0083, 0x0FFD, 0x007D, 0x0FFE, 0x0077, 0x0FFE, 0x0071, 0x0FFE, 0x006A, 0x0FFE,
426 0x0064, 0x0FFE, 0x005E, 0x0FFE, 0x0057, 0x0FFF, 0x0051, 0x0FFF, 0x004B, 0x0FFF, 0x0045, 0x0FFF,
427 0x003E, 0x0FFF, 0x0038, 0x0FFF, 0x0032, 0x0FFF, 0x002B, 0x0FFF, 0x0025, 0x0FFF, 0x001F, 0x0FFF,
428 0x0019, 0x0FFF, 0x0012, 0x0FFF, 0x000C, 0x0FFF, 0x0006, 0x0FFF,
429];
430
431lazy_static::lazy_static! {
432 static ref WORD_6A56C8: Vec<i16> = init_table();
433}
434
435fn init_table() -> Vec<i16> {
436 let mut table = Vec::with_capacity(0x10000);
437 let mut cx: i16 = 0;
438 let mut dx: i16 = 0;
439 for _ in 0..0x8000 {
440 table.push(dx);
441 wrapping! {
442 dx -= 1;
443 cx += 1;
444 }
445 table.push(cx);
446 }
447 table
448}
449
450struct PcmDecoder {
451 pcm_data: Vec<u8>,
452 encoded: MemReader,
453 pcm_size: usize,
454 extra: u32,
455 dword_43a214: Vec<i32>,
456 unk_6a16c8: Vec<u8>,
457 a2: Vec<i32>,
459 a3: Vec<i32>,
461}
462
463impl PcmDecoder {
464 pub fn new<R: Read + Seek>(
465 mut input: R,
466 pcm_size: usize,
467 extra: u32,
468 mode: Mode,
469 ) -> Result<Self> {
470 if extra > 4 {
471 return Err(anyhow::anyhow!("Unsupported PCM extra: {}", extra));
472 }
473 let packed_size = input.read_u32()?;
474 let pcm_data = vec![0u8; pcm_size + 8192];
475 let encoded = match mode {
476 Mode::Lzss => {
477 let mut data = vec![0u8; packed_size as usize];
478 input.read_exact(&mut data)?;
479 Self::unpack_v1(&data)?
480 }
481 Mode::Zlib => {
482 let mut decoder = flate2::read::ZlibDecoder::new(input);
483 let mut data = Vec::new();
484 decoder.read_to_end(&mut data)?;
485 data
486 }
487 _ => return Err(anyhow::anyhow!("Unsupported PCM mode: {:?}", mode)),
488 };
489 Ok(Self {
490 pcm_data,
491 encoded: MemReader::new(encoded),
492 pcm_size,
493 extra,
494 dword_43a214: vec![0; 0x10],
495 unk_6a16c8: vec![0; 0x2000],
496 a2: vec![0; 0x1000],
497 a3: vec![0; 0x1000],
498 })
499 }
500
501 pub fn unpack(mut self) -> Result<Vec<u8>> {
502 let mut reader = MemReaderRef::new(&UNK_43A254);
503 reader.pos = self.extra as usize * 0x40;
504 for i in 0..0x10 {
505 self.dword_43a214[i] = reader.read_i32()?;
506 }
507 self.decode_v1()?;
508 self.pcm_data.truncate(self.pcm_size);
509 Ok(self.pcm_data)
510 }
511
512 fn decode_v1(&mut self) -> Result<()> {
513 let v14 = self.pcm_size / 2;
514 let mut v5 = 0;
515 let mut decoded = 0;
516 let mut dst_sizea = 0;
517 while dst_sizea < v14 {
518 self.sub_4121c0(v5)?;
519 v5 += 8192;
520 self.sub_411ab0(12);
521 let mut v6 = decoded;
522 let mut v7 = 0;
523 let mut v8 = 0;
524 let mut v9 = 32;
525 while v9 > -4064 {
526 if v7 + dst_sizea < v14 {
527 let mut v11;
528 if v9 > 0 && dst_sizea != 0 {
529 let v10 = (v7 as i64).wrapping_mul(self.a2[v8] as u32 as i64)
530 + (v9 as i64).wrapping_mul(i16::from_le_bytes([
531 self.pcm_data[v6],
532 self.pcm_data[v6 + 1],
533 ]) as i64);
534 v11 = (((v10 >> 32) & 0x1F) as i32 + v10 as i32) >> 5;
535 } else {
536 v11 = self.a2[v8];
537 }
538 if v11 > 32767 {
539 v11 = 32767;
540 } else if v11 < -32768 {
541 v11 = -32768;
542 }
543 let data = (v11 as i16).to_le_bytes();
544 self.pcm_data[v6] = data[0];
545 self.pcm_data[v6 + 1] = data[1];
546 }
547 v7 += 1;
548 v6 += 2;
549 v8 += 1;
550 v9 -= 1;
551 }
552 decoded += 8128;
553 dst_sizea += 4064;
554 }
555 Ok(())
556 }
557
558 fn sub_4121c0(&mut self, a1: usize) -> Result<()> {
559 let mut v1 = a1;
560 let mut v5 = 1;
561 for _ in 0..0x1000 {
562 self.unk_6a16c8[v5] = self.encoded.cpeek_u8_at(v1 as u64)?;
563 v1 += 1;
564 v5 += 2;
565 }
566 v5 = 0;
567 for _ in 0..0x800 {
568 let v7 = self.encoded.cpeek_u8_at(v1 as u64 + 0x800)?;
569 let v8 = self.encoded.cpeek_u8_at(v1 as u64)?;
570 self.unk_6a16c8[v5] = (v7 >> 4) | (v8 & 0xF0);
571 self.unk_6a16c8[v5 + 2] = (v8 << 4) | (v7 & 0x0F);
572 v5 += 4;
573 v1 += 1;
574 }
575 let mut v9 = 0;
576 v5 = 0;
577 for v11_chunk in (0..32768).step_by(16) {
578 let result = self.dword_43a214[v11_chunk / 0x1000];
579 let i1 = u16::from_le_bytes([self.unk_6a16c8[v5], self.unk_6a16c8[v5 + 1]]) as usize;
580 let i2 =
581 u16::from_le_bytes([self.unk_6a16c8[v5 + 2], self.unk_6a16c8[v5 + 3]]) as usize;
582 self.a2[v9] = result.wrapping_mul(WORD_6A56C8[i1] as i32);
583 self.a3[v9] = result.wrapping_mul(WORD_6A56C8[i2] as i32);
584 v9 += 1;
585 v5 += 4;
586 }
587 for i in v9..4096 {
588 self.a2[i] = 0;
589 self.a3[i] = 0;
590 }
591 Ok(())
592 }
593
594 fn sub_411ab0(&mut self, a1: i32) {
595 let mut v4 = 1 << a1;
596 let mut v5 = 1;
597 let mut v68 = 1;
598 let mut v6 = 1 << a1;
599 let v79 = 1 << a1;
600 if a1 >= 3 {
601 let mut v7 = v4 >> 1;
602 let mut v59 = a1 - 2;
603 loop {
604 let v63 = v4;
605 let v82 = DWORD_43A358[v5 as usize * 2];
606 let v66 = v7;
607 let mut v8 = v7 >> 1;
608 let v62 = v7 >> 1;
609 let v80 = DWORD_43A358[1 + 2 * v5 as usize];
610 let mut v77 = 0;
611 if v6 > 0 {
612 let mut v73 = 0;
613 let mut v69 = v8;
614 let mut v75 = v7;
615 let v9 = v8 + 1;
616 let v10 = v7 + v8;
617 let mut v64 = v9;
618 let mut v11 = 1;
619 let mut v12 = v10 + 1;
620 let mut v71 = v10;
621 let mut v13 = v7 + 1;
622 loop {
623 let v14 = self.a2[v75 as usize];
624 let v15 = self.a2[v73 as usize];
625 let v16 = self.a3[v11 as usize - 1] - self.a3[v13 as usize - 1];
626 self.a2[v73 as usize] += self.a2[v75 as usize];
627 self.a3[v11 as usize - 1] += self.a3[v13 as usize - 1];
628 self.a2[v75 as usize] = v15 - v14;
629 self.a3[v13 as usize - 1] = v16;
630 let v17 = self.a2[v13 as usize];
631 let v18 = self.a2[v11 as usize] - v17;
632 let v19 = self.a3[v11 as usize] - self.a3[v13 as usize];
633 self.a2[v11 as usize] += v17;
634 self.a3[v11 as usize] += self.a3[v13 as usize];
635 self.a2[v13 as usize] = (((v18 as i64).wrapping_mul(v82 as i64) as u64
636 >> 12)
637 + ((v19 as i64).wrapping_mul(v80 as i64) as u64 >> 12))
638 as i32;
639 let pv = (v19 as i64).wrapping_mul(v82 as i64) as u64 >> 12;
640 let nv = (v18 as i64).wrapping_mul(v80 as i64) as u64 >> 12;
641 self.a3[v13 as usize] = pv.wrapping_sub(nv) as i32;
642 let v20 = self.a2[v69 as usize] - self.a2[v71 as usize];
643 let v21 = v64;
644 let v22 = self.a3[v64 as usize - 1] - self.a3[v12 as usize - 1];
645 self.a2[v69 as usize] += self.a2[v71 as usize];
646 self.a3[v21 as usize - 1] += self.a3[v12 as usize - 1];
647 self.a2[v71 as usize] = v22;
648 self.a3[v12 as usize - 1] = -v20;
649 let v23 = self.a2[v12 as usize];
650 let v24 = self.a2[v64 as usize] - v23;
651 let v25 = self.a3[v64 as usize] - self.a3[v12 as usize];
652 self.a2[v21 as usize] += v23;
653 self.a3[v21 as usize] += self.a3[v12 as usize];
654 let pv = (v25 as i64).wrapping_mul(v82 as i64) as u64 >> 12;
655 let nv = (v24 as i64).wrapping_mul(v80 as i64) as u64 >> 12;
656 self.a2[v12 as usize] = pv.wrapping_sub(nv) as i32;
657 self.a3[v12 as usize] = (-((((v24 as i64).wrapping_mul(v82 as i64) as u64
658 >> 12)
659 + ((v25 as i64).wrapping_mul(v80 as i64) as u64 >> 12))
660 as i64)) as i32;
661 v13 += v63;
662 v75 += v63;
663 v11 += v63;
664 v73 += v63;
665 v12 += v63;
666 v71 += v63;
667 v77 += v63;
668 v69 += v63;
669 v64 += v63;
670 if v77 >= v79 {
671 break;
672 }
673 }
674 v8 = v62;
675 v5 = v68;
676 v7 = v66;
677 v6 = 1 << a1;
678 }
679 if v8 > 2 {
680 let mut v70 = 2;
681 let mut v72 = v7 + 2;
682 let mut v74 = v8 + 2;
683 let mut v27 = 1 + 4 * v5;
684 let mut v60 = v8 - 2;
685 let mut v76 = v8 + 2 + v7;
686 loop {
687 let v83 = DWORD_43A358[v27 as usize - 1];
688 let v81 = DWORD_43A358[v27 as usize];
689 let mut v78 = 0;
690 if v6 > 0 {
691 let mut v28 = v70;
692 let mut v29 = v72;
693 let mut v65 = v74;
694 let mut v85 = v76;
695 loop {
696 let v31 = self.a2[v29 as usize];
697 let v32 = self.a2[v28 as usize] - v31;
698 let v33 = self.a3[v28 as usize] - self.a3[v29 as usize];
699 self.a2[v28 as usize] += v31;
700 self.a3[v28 as usize] += self.a3[v29 as usize];
701 self.a2[v29 as usize] =
702 (((v32 as i64).wrapping_mul(v83 as i64) as u64 >> 12)
703 + ((v33 as i64).wrapping_mul(v81 as i64) as u64 >> 12))
704 as i32;
705 let pv = (v33 as i64).wrapping_mul(v83 as i64) as u64 >> 12;
706 let nv = (v32 as i64).wrapping_mul(v81 as i64) as u64 >> 12;
707 self.a3[v29 as usize] = pv.wrapping_sub(nv) as i32;
708 let v34 = self.a2[v65 as usize] - self.a2[v85 as usize];
709 let v35 = self.a3[v65 as usize] - self.a3[v85 as usize];
710 self.a2[v65 as usize] += self.a2[v85 as usize];
711 self.a3[v65 as usize] += self.a3[v85 as usize];
712 let pv = (v35 as i64).wrapping_mul(v83 as i64) as u64 >> 12;
713 let nv = (v34 as i64).wrapping_mul(v81 as i64) as u64 >> 12;
714 self.a2[v85 as usize] = pv.wrapping_sub(nv) as i32;
715 self.a3[v85 as usize] =
716 (-((((v34 as i64).wrapping_mul(v83 as i64) as u64 >> 12)
717 + ((v35 as i64).wrapping_mul(v81 as i64) as u64 >> 12))
718 as i64)) as i32;
719 v29 += v63;
720 v85 += v63;
721 v28 += v63;
722 v65 += v63;
723 v78 += v63;
724 if v78 >= v79 {
725 break;
726 }
727 }
728 v5 = v68;
729 v6 = 1 << a1;
730 }
731 v27 += 2 * v5;
732 v70 += 1;
733 v72 += 1;
734 v74 += 1;
735 v76 += 1;
736 v60 -= 1;
737 if v60 == 0 {
738 break;
739 }
740 }
741 }
742 v68 = 2 * v5;
743 v59 -= 1;
744 if v59 == 0 {
745 break;
746 }
747 v7 = v62;
748 v5 *= 2;
749 v4 = v66;
750 }
751 }
752 if !(a1 < 2 || v6 <= 0) {
753 let mut v37 = 1;
754 let mut v38 = 3;
755 let mut v88 = (v6 as u32 + 3) >> 2;
756 loop {
757 let v39 = self.a2[v37 as usize - 1];
758 let v40 = self.a2[v37 as usize + 1];
759 let v41 = self.a3[v38 as usize - 3] - self.a3[v38 as usize - 1];
760 self.a2[v37 as usize - 1] = v40 + v39;
761 v37 += 4;
762 self.a3[v38 as usize - 3] += self.a3[v38 as usize - 1];
763 self.a2[v37 as usize - 3] = v39 - v40;
764 self.a3[v38 as usize - 1] = v41;
765 let v42 = self.a2[v38 as usize];
766 let v43 = self.a3[v38 as usize - 2] - self.a3[v38 as usize];
767 v38 += 4;
768 let v44 = self.a2[v37 as usize - 4] - v42;
769 self.a2[v37 as usize - 4] += v42;
770 self.a3[v38 as usize - 6] += self.a3[v38 as usize - 4];
771 self.a2[v38 as usize - 4] = v43;
772 self.a3[v38 as usize - 4] = -v44;
773 v88 -= 1;
774 if v88 == 0 {
775 break;
776 }
777 }
778 v6 = v79;
779 }
780 let mut v45 = 0;
781 if v6 > 0 {
782 let mut v47 = 1;
783 let mut v89 = (v79 as u32 + 1) >> 1;
784 loop {
785 let v48 = self.a2[v47 as usize];
786 let v49 = self.a3[v47 as usize - 1] - self.a3[v47 as usize];
787 let v50 = self.a2[v45 as usize] - v48;
788 v47 += 2;
789 self.a2[v45 as usize] += v48;
790 v45 += 2;
791 self.a3[v47 as usize - 3] += self.a3[v47 as usize - 2];
792 self.a2[v47 as usize - 2] = v50;
793 self.a3[v47 as usize - 2] = v49;
794 v89 -= 1;
795 if v89 == 0 {
796 break;
797 }
798 }
799 v45 = 0;
800 v6 = v79;
801 }
802 let mut v51 = 0;
803 let mut result = v6 / 2;
804 let v67 = v6 / 2;
805 let mut v90 = 1;
806 if v6 - 1 > 1 {
807 let mut v54 = 1;
808 loop {
809 while result <= v51 {
810 v51 -= result;
811 result /= 2;
812 }
813 v51 += result;
814 if v90 < v51 {
815 self.a2.swap((v45 + v51) as usize, v54 as usize);
816 self.a3.swap(v51 as usize, v54 as usize);
817 }
818 v54 += 1;
819 v90 += 1;
820 if v90 >= v79 - 1 {
821 break;
822 }
823 result = v67;
824 }
825 v6 = v79;
826 }
827 while v6 > 0 {
828 let eax = self.a2[v45] << 4;
829 let edx = if eax < 0 { 0x3FFF } else { 0 };
830 self.a2[v45] = eax.wrapping_add(edx) >> 14;
831 v45 += 1;
832 v6 -= 1;
833 }
834 }
835
836 fn unpack_v1(input: &[u8]) -> Result<Vec<u8>> {
837 let packed_size = input.len();
838 let mut flag = 0;
839 let mut src = 0;
840 let mut output = Vec::new();
841 while src < packed_size {
842 flag >>= 1;
843 if (flag & 0x100) == 0 {
844 flag = input[src] as u32 | 0xFF00;
845 src += 1;
846 }
847 if (flag & 1) != 0 {
848 output.push(input[src]);
849 src += 1;
850 } else {
851 if src >= packed_size {
852 break;
853 }
854 let mut offset;
855 let count;
856 let ctl = input[src] as u32;
857 src += 1;
858 if ctl >= 0xc0 {
859 offset = input[src] as usize | (((ctl & 3) << 8) as usize);
860 src += 1;
861 count = 4 + ((ctl >> 2) & 0xF) as usize;
862 } else if ctl & 0x80 != 0 {
863 offset = (ctl & 0x1F) as usize;
864 count = (2 + ((ctl >> 5) & 3)) as usize;
865 if offset == 0 {
866 offset = input[src] as usize;
867 src += 1;
868 }
869 } else if ctl == 0x7F {
870 count = (2 + u16::from_le_bytes([input[src], input[src + 1]])) as usize;
871 offset = u16::from_le_bytes([input[src + 2], input[src + 3]]) as usize;
872 src += 4;
873 } else {
874 offset = u16::from_le_bytes([input[src], input[src + 1]]) as usize;
875 src += 2;
876 count = (ctl + 4) as usize;
877 }
878 let dst = output.len();
879 let copy_src = dst - offset;
880 for i in 0..count {
881 output.push(output[copy_src + i]);
882 }
883 }
884 }
885 Ok(output)
886 }
887}